using System;
using System.Collections;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using PHSRAG.Insight21.CDS;
using PHSRAG.Insight21.Common;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Policy;
using PHSRAG.Utility;

namespace PHSRAG.Insight21.COI
{
    /// <summary>
    /// This page allows a user with supervisor and / or Super-user access privilege to add external users. 
    /// </summary>
    public partial class AddExternal : BasePage
    {
        #region Instance variable: Private

        private ICachePolicy _applicationCachePolicy;
        private ICachePolicy _cachePolicy;
        private Hashtable _pageCache;
        private ICachePolicy _pageCachePolicy;

        /// <summary>
        ///This flag is used to decide whether or not the headers should be displayed
        ///If the page is to be displayed as a popup, then the header section is made invisible
        /// </summary>
        private bool _showAsPopUp;

        private ArrayList _states;

        #endregion

        #region Constants

        /// <summary>annunciator's general message</summary>
        private const string AnnunciatorTitle = "The following error(s) occurred...";

        private const string DegreeIDColumn = "Id";
        private const string DegreesNameColumn = "Name";

        /// <summary>used to uniquely identify or load the degree values in the cache</summary>
        private const string ExternalDegreesKey = "ExternalDegreesKey_3B8CA1A8-2652-45e5-B6E4-045DD45AD601";

        /// <summary>used to uniquely identify or load the state values in the cache</summary>
        private const string ExternalStatesKey = "ExternalStatesKey_C14E27BF-382B-4ff9-BFC1-56E44077A45D";

        /// <summary>used to uniquely identify or load the value in the page cache</summary>
        private const string PageCacheKey = "AddExternalCOIPageKey_5B25A5F3-2943-4d10-9D46-817BC12E0E44";

        private const string RefCodeCodeColumn = "Code";

        /// <summary>The following represent the database columns</summary>
        private const string RefCodeMeaningColumn = "Meaning";

        #endregion

        #region Properties

        /// <summary>
        /// Get the valid list of degrees (rows of id/name pairs).
        /// This maintains the relationship between degrees and their corresponding ids for binding
        /// to the degree dropdownlist
        /// </summary>
        private DataTable Degrees
        {
            get
            {
                DataTable degrees = _pageCache[ExternalDegreesKey] as DataTable;
                if (degrees == null)
                {
                    degrees = Person.GetDegreeTypes(DataAccess.ConnectionString);
                    _pageCache[ExternalDegreesKey] = degrees;
                    _pageCachePolicy.Cache(PageCacheKey, _pageCache);
                }
                return degrees;
            }
        }

        /// <summary>
        /// Gets an arraylist of US State's refCodes to be bound to the States dropdownlist
        /// </summary>
        private ArrayList States
        {
            get
            {
                _states = _pageCache[ExternalStatesKey] as ArrayList;
                if (_states == null)
                {
                    RefCodes refs = (RefCodes) _applicationCachePolicy.GetCachedObject(RefCodes.CacheKey);
                    _states = refs.GetRefCodes(Humans.Constants.States.Domain);
                    _pageCache[ExternalStatesKey] = _states;
                    _pageCachePolicy.Cache(PageCacheKey, _pageCache);
                }
                return _states;
            }
        }

        #endregion

        #region event handlers

        /// <summary>
        /// Page load event handler
        /// </summary>
        /// <param name="sender">Sender,that raised the event</param>
        /// <param name="e">arguments pertaining to the sender</param>
        protected void OnPageLoad(object sender, EventArgs e)
        {
            try
            {
                breadCrumb.Add(
                    "Add external users",
                    "AddExternal.aspx",
                    Settings.GetKeyValue("BreadCrumb.SummaryLevel", 1));

                _pageCache = _pageCachePolicy.GetCachedObject(PageCacheKey) as Hashtable;

                if (!IsPostBack)
                {
                    if (_pageCache == null)
                    {
                        _pageCache = new Hashtable();
                    }

                    /* Get id coming from the originating page and clean the cache of all incoming data */
                    Hashtable incomingPageHash =
                        _cachePolicy.GetCachedObject(Keys.IncomingDataKey) as Hashtable;
                    if (incomingPageHash != null)
                    {
                        if (incomingPageHash.ContainsKey(Keys.ShowAsPopUp))
                        {
                            _showAsPopUp = Convert.ToBoolean(incomingPageHash[Keys.ShowAsPopUp]);
                        }
                    }
                    _pageCache[Keys.ShowAsPopUp] = _showAsPopUp;
                    _pageCachePolicy.Cache(PageCacheKey, _pageCache);

                    state.DataSource = States;
                    state.DataTextField = RefCodeMeaningColumn;
                    state.DataValueField = RefCodeCodeColumn;
                    state.DataBind();

                    degree.DataSource = Degrees;
                    degree.DataTextField = DegreesNameColumn;
                    degree.DataValueField = DegreeIDColumn;
                    degree.DataBind();
                }
                else
                {
                    _showAsPopUp = (bool) _pageCache[Keys.ShowAsPopUp];
                }
                //if page is being shown as popup, then hide the header section
                headerSection.Visible = !_showAsPopUp;
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Resets the subnavigation selected link before the header performs a redirect.
        /// </summary>
        /// <param name="sender">Control that rasied the event.</param>
        /// <param name="e">Arguments pertaining to the event.</param>
        private void OnNavigate(object sender, CommandEventArgs e)
        {
            try
            {
                coiSubNavigation.Reset();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Handles the cancel button click and closes itself without adding the external person
        /// </summary>
        /// <param name="sender">sender of the event</param>
        /// <param name="e">arguments of the event</param>
        private void OnCancel(object sender, ImageClickEventArgs e)
        {
            try
            {
                CloseCurrentWindow();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Handles the save button click (saves the external person)and redirects back 
        /// to the Hierarchy Maintenance page.
        /// </summary>
        /// <param name="sender">sender of the event</param>
        /// <param name="e">arguments of the event</param>
        private void OnSave(object sender, ImageClickEventArgs e)
        {
            try
            {
                //Check for invalid data.
                if (Page.IsValid)
                {
                    //Instantiate a new COI User object,if the entered data are valid
                    AddNewCOIUser();
                }
                //Script for popup window that displays the attachment
                string script = "\n<script language=JavaScript id='displaySusccessMessage'>\n" +
                    "alert('External User added to database.  To Add this external user to the hierarchy, search for, select, and click Add to List. Select again and click Add to Hierarchy.')\n" +
                        "</script>";

                //Check whether the script is already registered
                if (!ClientScript.IsClientScriptBlockRegistered("displaySusccessMessage"))
                {
                    //Register the script
                    ClientScript.RegisterClientScriptBlock(GetType(), "displaySusccessMessage", script);
                }
                CloseCurrentWindow();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Closes the current popup window using javascript
        /// </summary>
        private void CloseCurrentWindow()
        {
            ClientScript.RegisterStartupScript(GetType(), "CloseWindow", "<script>javascript:window.close();</script>");
        }

        /// <summary>
        /// Instantiates a COIUser object and adds the external Person object
        /// </summary>
        private void AddNewCOIUser()
        {
            COIUser coiUser = new COIUser(_cachePolicy);

            coiUser.LastName = lastName.Text;
            coiUser.FirstName = firstName.Text;
            coiUser.MiddleName = middleName.Text;
            coiUser.AdmPersonType = (int) Person.PersonType.External;
            coiUser.OrganizationName = institution.Text;
            coiUser.Department = department.Text;
            coiUser.PhoneArea = telephone.AreaCode;
            coiUser.PhoneNumber = String.Format("{0}-{1}", telephone.Exchange, telephone.Phone);
            coiUser.Email = email.Email;
            coiUser.DegreeId = Convert.ToInt32(degree.SelectedValue);
            coiUser.Title = institutionTitle.Text;
            coiUser.FaxArea = fax.AreaCode;
            coiUser.FaxNumber = (fax.Phone == string.Empty) ? string.Empty :
                                                                               String.Format("{0}-{1}", fax.Exchange, fax.Phone);

            Address address = coiUser.Address;
            address.Address1 = address1.Text;
            address.Address2 = address2.Text;
            address.City = city.Text;
            address.Zip = zip.Text;
            address.StateCode = state.SelectedValue;
            coiUser.Save(DataAccess.ConnectionString);
        }

        /// <summary>
        /// Resets all input-type controls on the page to their default values
        /// </summary>
        private void ResetControls()
        {
            lastName.Text = firstName.Text = middleName.Text = address1.Text = address2.Text = city.Text =
                institution.Text = department.Text = institutionTitle.Text = zip.Text = string.Empty;

            state.DataSource = States;
            state.DataTextField = RefCodeMeaningColumn;
            state.DataValueField = RefCodeCodeColumn;
            state.DataBind();

            degree.DataSource = Degrees;
            degree.DataTextField = DegreesNameColumn;
            degree.DataValueField = DegreeIDColumn;
            degree.DataBind();

            telephone.Reset();
            email.Reset();
            fax.Reset();
        }

        /// <summary>
        /// Displays an error message on the screen to the user with the exception, and all
        /// inner exception messages.
        /// </summary>
        /// <param name="ex">The exception to report on</param>
        private void DisplayExceptionReport(Exception ex)
        {
            annunciator.Title = AnnunciatorTitle;
            annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
        }

        #endregion

        #region Web Form Designer generated code

        protected override void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);
            _cachePolicy = (Policy.ICachePolicy) Session[Policy.Names.CachePolicyKey];
            _pageCachePolicy = (Policy.ICachePolicy) Session[Policy.Names.PageCachePolicyKey];
            _applicationCachePolicy =
                (Policy.ICachePolicy) Application[Policy.Names.ApplicationCachePolicyKey];
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.header.Navigate += new System.Web.UI.WebControls.CommandEventHandler(this.OnNavigate);
            this.formCancel.Click += new ImageClickEventHandler(OnCancel);
            this.formSave.Click += new ImageClickEventHandler(OnSave);
            this.Load += new System.EventHandler(this.OnPageLoad);
        }

        #endregion
    }
}